package com.jueban.serviceImpl;

import com.jueban.Vo.UploadFileVo;
import com.jueban.model.ApplyOfIP;
import com.jueban.model.FilePath;
import com.jueban.model.user.User;
import com.jueban.service.FileConversionService;
import com.jueban.service.FileService;
import com.jueban.util.Messages;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.ConnectException;

@Service
@EnableAsync
public class FileServiceImpl implements FileService {

    private final String APPLY_FILE_NAME = "申请资料";
    private final String PROXY_FILE_NAME = "代理通知书";
    private final String AUTHORIZED_FILE_NAME = "授权证书";

    //获取文件存放目录
    private final FilePath filePath;

    @Value("${file.path}")
    private String path;

    private final FileConversionService fileConversionService;

    @Autowired
    public FileServiceImpl(FilePath filePath, FileConversionService fileConversionService) {
        this.filePath = filePath;
        this.fileConversionService = fileConversionService;
    }

    /**
     * 并将文件保存到用户指定文件夹下
     *
     * @param file：用户上传的文件
     * @return 携带保存成功与否信息：
     * 成功: 加入上传成功信息，加入路径
     * 失败：加入上传失败信息
     */
    @Override
    @PreAuthorize("isAuthenticated()")
    public UploadFileVo uploadFile(MultipartFile file) {
        UploadFileVo resultVo = new UploadFileVo();
        String folderPath = filePath.getPath() + "/" + "cache" + "/";
        File folder = new File(folderPath);
        if (!folder.exists()) {
            boolean success = folder.mkdirs();
            if (!success) {
                resultVo.setFailed();
                resultVo.setMessages(Messages.UPLOAD_FILE_FAIL);
                return resultVo;
            }
        }

        File newFile = new File(folderPath + "/" + file.getOriginalFilename());
        if (newFile.exists()) {
            resultVo.setFailed();
            resultVo.setMessages(Messages.UPLOAD_FILE_FAIL);
            return resultVo;
        }
        try {
            file.transferTo(newFile);
        } catch (IOException e) {
            resultVo.setFailed();
            resultVo.setMessages(Messages.UPLOAD_FILE_FAIL);
            return resultVo;
        }
        resultVo.setSucceeded();
        resultVo.setMessages(Messages.UPLOAD_FILE_SUCCED);
        resultVo.setFilePath("cache/" + file.getOriginalFilename());
        return resultVo;
    }

    @Override
    public File getFileByPath(String path) {
        //File file = new File(filePath.getPath() + path);
        return new File(filePath.getPath() + path);
    }

    @Override
    public boolean transferInformationFile(ApplyOfIP applyOfIP, User user) {
        File oldFile = new File(filePath.getPath() + applyOfIP.getInformationPath());
        String fileName = oldFile.getName();
        String suffix = fileName.substring(fileName.lastIndexOf('.'));
        File newFile = new File(filePath.getPath()
                + user.getDepartment() + "/" + user.getId() + "/"
                + applyOfIP.getApplyInfo().getApplyIPName() + applyOfIP.getId());
        if (!oldFile.exists()) return false;
        if (!newFile.mkdirs()) return false;
        newFile = new File(newFile.getPath() + "/" + "申请资料" + suffix);
        boolean result = oldFile.renameTo(newFile);
        if (result) {
            applyOfIP.setInformationPath(newFile.toString().substring(filePath.getPath().length()));
            return true;
        } else return false;
    }

    @Override
    public boolean saveApplyFile(ApplyOfIP applyOfIP, MultipartFile file) {
        String path = getPath(applyOfIP);
        if (createPathIfNotExists(path)) {
            String fileName = file.getOriginalFilename();
            String suffix = fileName.substring(fileName.lastIndexOf('.'));
            path += "/" + APPLY_FILE_NAME + suffix;
            boolean result = saveFile(file, path);
            if (result) {
                fileConversionService.doc2Pdf(new File(path));
            }
            return result;
        }

        return false;
    }

    @Override
    public File getApplyFile(ApplyOfIP applyOfIP) {
        String path = getPath(applyOfIP) + "/";
        String suffix = ".doc";
        File file = new File(path + APPLY_FILE_NAME + suffix);

        if (file.exists()) {
            return file;
        }
        suffix = ".docx";

        file = new File(path + APPLY_FILE_NAME + suffix);

        if (file.exists()) {
            return file;
        } else {
            return null;
        }

    }

    @Override
    public boolean saveProxyFile(ApplyOfIP applyOfIP, MultipartFile file) {
        String path = getPath(applyOfIP);
        if (createPathIfNotExists(path)) {
            path += "/" + PROXY_FILE_NAME + ".pdf";
            return saveFile(file, path);
        }
        return false;
    }

    @Override
    public File getProxyFile(ApplyOfIP applyOfIP) {
        String path = getPath(applyOfIP) + "/";
        String suffix = ".pdf";
        File file = new File(path + PROXY_FILE_NAME + suffix);

        if (file.exists()) {
            return file;
        } else {
            return null;
        }
    }


    @Override
    public boolean saveAuthorizedFile(ApplyOfIP applyOfIP, MultipartFile file) {
        String path = getPath(applyOfIP);
        if (createPathIfNotExists(path)) {
            path += "/" + AUTHORIZED_FILE_NAME + ".pdf";
            return saveFile(file, path);
        }
        return false;
    }

    @Override
    public File getAuthorizedFile(ApplyOfIP applyOfIP) {
        String path = getPath(applyOfIP) + "/";
        String suffix = ".pdf";
        File file = new File(path + AUTHORIZED_FILE_NAME + suffix);

        if (file.exists()) {
            return file;
        } else {
            return null;
        }
    }


    /**
     * 根据路径保存文件
     *
     * @param file 文件
     * @param path 路径
     * @return 保存结果
     */
    private boolean saveFile(MultipartFile file, String path) {
        File newFile = new File(path);
        try {
            file.transferTo(newFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 若该路径未创建则创建
     *
     * @param path 路径
     * @return 创建结果
     */
    private boolean createPathIfNotExists(String path) {
        File folder = new File(path);
        if (!folder.exists()) {
            return folder.mkdirs();
        } else {
            return true;
        }
    }

    private String getPath(ApplyOfIP applyOfIP) {
        User user = applyOfIP.getApplicant();
        return filePath.getPath() + "/" + user.getDepartment() + "/" + user.getId() + "/"
                + applyOfIP.getApplyInfo().getApplyIPName();
    }


}
